package com.dragon.modules.yuegou.web;

import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

/**
 * 树遍历器
 * 
 * @author liuwu
 * @date 2018年3月5日
 *
 * @param <E>
 *            树节点元素类型
 */
public interface TreeIterator<E> extends Iterator<E> {

	/**
	 * 返回上一个返回节点的深度, {@code dept}方法只能在{@link #next()}后调用.
	 * 
	 * @return depth
	 * @throws IllegalStateException
	 *             如果{@code next}方法还没有被调用, 或者{@code next}方法调用后以及进行了一次
	 *             {@code remove}操作
	 */
	int depth();

	/**
	 * 为上一个返回的节点设置元素,{@code set}操作只能在{@link #next()}后进行.
	 * 
	 * @param element
	 *            新的元素
	 * @throws UnsupportedOperationException
	 *             如果这个遍历器不支持 {@code set}操作
	 * @throws IllegalStateException
	 *             如果{@code next}方法还没有被调用, 或者{@code next}方法调用后以及进行了一次
	 *             {@code remove}操作
	 */
	void set(E element);

	/**
	 * 移除这个遍历器上一个返回的元素所在的子树. 被移除的子树里所有的元素都会被移除, 移除后此遍历器将无法遍历到这些元素.
	 * {@code remove}操作只能在{@link #next()}后进行,
	 * 并且每次调用{@link #next()}后最多进行一次{@code remove}操作.
	 * 
	 * @throws UnsupportedOperationException
	 *             如果这个遍历器不支持 {@code remove}操作
	 *
	 * @throws IllegalStateException
	 *             如果{@code next}方法还没有被调用, 或者{@code next}方法调用后以及进行了一次
	 *             {@code remove}操作
	 */
	void remove();

	/**
	 * 剪除这个遍历器上一个返回的元素所在的子树. 被移除的子树里所有的元素都会被移除, 移除后此遍历器将无法遍历到这些元素.
	 * {@code cut}操作只能在{@link #next()}后进行,
	 * 并且每次调用{@link #next()}后最多进行一次{@code remove/cut}操作.
	 * 
	 * <p>
	 * 此方法与{@link #remove()}方法没有任何区别, 除了会返回被删除的子树. 所以要进行{@code remove}操作时这两个方法只能选其一.
	 * 
	 * @return 被移除的子树
	 * @throws UnsupportedOperationException
	 *             如果这个遍历器不支持 {@code cut}操作
	 * @throws IllegalStateException
	 *             如果{@code next}方法还没有被调用, 或者{@code next}方法调用后已经进行了一次
	 *             {@code remove/cut}操作
	 */
	Tree<E> cut();

	Tree<E> get();

	/**
	 * 对上一个返回节点的直接子节点进行排序 , {@code sort}操作只能在{@link #next()}后进行.
	 * 
	 * <p>
	 * 不论是宽度优先还是深度优先遍历, 遍历到某个节点时其子节点一定处于尚未遍历的状态(如果有).
	 * 
	 * @param c
	 *            排序比较器
	 * @throws UnsupportedOperationException
	 *             如果这个遍历器不支持 {@code sort}操作
	 * @throws IllegalStateException
	 *             如果{@code next}方法还没有被调用, 或者{@code next}方法调用后已经进行了一次
	 *             {@code remove}操作
	 */
	void sort(Comparator<E> c);

	/**
	 * 当遍历到某个节点之后, 跳过其子节点, 继续遍历其它节点. {@code skipChilds}操作只能在{@link #next()}后进行.
	 * 
	 * @throws UnsupportedOperationException
	 *             如果这个遍历器不支持 {@code skipChilds}操作
	 * @throws IllegalStateException
	 *             如果{@code next}方法还没有被调用, 或者{@code next}方法调用后已经进行了一次
	 *             {@code remove/cut}操作
	 */
	void skipChilds();

	/**
	 * 当遍历到某个节点之后, 遍历其子节点, 不再遍历其它节点. {@code iterateChilds}操作只能在{@link #next()}后进行.
	 * 
	 * @throws UnsupportedOperationException
	 *             如果这个遍历器不支持 {@code iterateChilds}操作
	 * @throws IllegalStateException
	 *             如果{@code next}方法还没有被调用, 或者{@code next}方法调用后已经进行了一次
	 *             {@code remove/cut}操作
	 */
	void iterateChilds();

	/**
	 * 获取从根节点到上一个遍历的节点的路径. 本方法只能在{@link #next()}后调用.
	 * 
	 * @return 路径列表
	 * @throws UnsupportedOperationException
	 *             如果这个遍历器不支持 {@code iterateChilds}操作
	 * @throws IllegalStateException
	 *             如果{@code next}方法还没有被调用, 或者{@code next}方法调用后已经进行了一次
	 *             {@code remove/cut}操作
	 */
	List<E> path();
	
	List<E> childs();
}
